/*
   Copyright (c) [Year] [name of copyright holder]
   [Software Name] is licensed under Mulan PSL v2.
   You can use this software according to the terms and conditions of the Mulan PSL v2. 
   You may obtain a copy of Mulan PSL v2 at:
            http://license.coscl.org.cn/MulanPSL2 
   THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.  
   See the Mulan PSL v2 for more details.  
*/

#ifndef JIAJIA_ARG_HPP
#define JIAJIA_ARG_HPP

#include"jiajiastd.hpp"

// 该文件是一些关于参数的一些操作
namespace jiajia{

    class jjcallstack{
    public:
        static constexpr size_t MAX_ARGS_SIZE = 1024;
        static constexpr size_t MAX_LAST_NUM = 256;

    private:
        my::buffer<value_t> mArgs;      // 存储所有参数的缓存
        unsigned int mArgsTop;          // 存储下次参数要插入的位置
        my::buffer<unsigned int> mLast; // 存储上次参数结束时要插入的位置
        unsigned int mLastTop;          // 存储下次参数结束时插入的位置

    public:
        jjcallstack():
            mArgs(MAX_ARGS_SIZE),
            mArgsTop(0),
            mLast(MAX_LAST_NUM),
            mLastTop(0)
        {}

        // 把当前要插入的位置设为新的开始
        void newArgs(){
            if(mLastTop >= MAX_LAST_NUM){
                return ;
            }

            mLast[mLastTop] = mArgsTop;
            ++mLastTop;
        }

        void pushArg(value_t * val){
            if(mArgsTop >= MAX_ARGS_SIZE){
                return ;
            }

            mArgs[mArgsTop].refto(val);
            ++mArgsTop;
        }

        void popArgs(){
            if(mLastTop == 0){
                return ;
            }

            mArgsTop = mLast[--mLastTop];
        }

        inline value_t * args(){
            if(mLastTop == 0)
                return nullptr;

            unsigned int pos = mLast[mLastTop-1];
            if(pos == mArgsTop)
                return nullptr;

            return &mArgs[pos];
        }

        size_t nums(){
            if(mLastTop == 0)
                return 0;
            return mArgsTop - mLast[mLastTop-1];
        }
    };
}

#endif
